package service

import (
	"booksmart/book/internal/domain"
	events "booksmart/book/internal/events/article"
	"booksmart/book/internal/repository/article"
	"context"
)

type ArticleService interface {
	Save(ctx context.Context, art domain.Article) (int64, error)
	Publish(ctx context.Context, art domain.Article) (int64, error)
	Withdraw(ctx context.Context, d domain.Article) error
	List(ctx context.Context, uid int64, offset int, limit int) ([]domain.Article, error)
	GetById(ctx context.Context, id int64) (domain.Article, error)
	GetPublishedById(ctx context.Context, id int64, uid int64) (domain.Article, error)
}

type articleService struct {
	repo     article.ArticleRepository
	producer events.Producer

	//author article.ArticleAuthorRepository
	//reader article.ArticleReaderRepository
}

func (a *articleService) GetPublishedById(ctx context.Context, id int64, uid int64) (domain.Article, error) {
	art, err := a.repo.GetPublishedById(ctx, id, uid)
	if err == nil {
		go func() {
			er := a.producer.ProducerReadEvent(ctx, events.ReadEvent{
				Uid: uid,
				Aid: art.Id,
			})
			if er != nil {
				//记录日志
			}
		}()
	}
	return art, err
}

func (a *articleService) GetById(ctx context.Context, id int64) (domain.Article, error) {
	return a.repo.GetByID(ctx, id)
}

func (a *articleService) List(ctx context.Context, uid int64, offset int, limit int) ([]domain.Article, error) {
	return a.repo.List(ctx, uid, offset, limit)
}

func NewArticleService(repo article.ArticleRepository) ArticleService {
	return &articleService{
		repo: repo,
	}
}

func (a articleService) Withdraw(ctx context.Context, art domain.Article) error {
	return a.repo.SyncStatus(ctx, art.Id, art.Author.Id, domain.ArticleStatusPrivate)
}

func (a articleService) Publish(ctx context.Context, art domain.Article) (int64, error) {
	//id, err := a.repo.Create(ctx, art)
	art.Status = domain.ArticleStatusPublished
	return a.repo.Sync(ctx, art)
}

func (a articleService) Save(ctx context.Context, art domain.Article) (int64, error) {
	art.Status = domain.ArticleStatusUnPublished
	if art.Id > 0 {
		err := a.repo.Update(ctx, art)
		return art.Id, err
	}
	return a.repo.Create(ctx, art)
}
